﻿// <copyright file="Program.cs" company="Hallvard Korsgaard">
//  Microsoft Public License (Ms-PL). See license details here: http://enoceannet.codeplex.com/license
// </copyright>
// <author>Hallvard Korsgaard</author>

namespace ChangeSettings
{
  using System;
  using System.Net;
  using System.Text;
  using StcEthernet;
  using StcEthernet.Management;

  /// <summary>
  /// Shows how to find STC-Ethernet transievers on the LAN and change their settings.
  /// </summary>
  public class Program
  {
    /// <summary>
    /// This variable is used for synchronizing write access to the console.
    /// </summary>
    private static readonly object lck = new object();

    /// <summary>
    /// Application starts here.
    /// </summary>
    public static void Main()
    {
      Settings settings;

      // Create the Settings object. This will create a UDP socket on port 5001 that listens for incomming data.
      settings = new Settings();

      // Hook up the TransieverInfoReceived event. This event fires when information is received from a trasiever.
      settings.TransieverInfoReceived += new EventHandler<StcEthernet.TransieverInfoReceivedEventArgs>(TransieverInfoReceived);

      // Hook up the UnknownTelegramReceived event. This event fires if unrecognizable information is received.
      settings.UnknownTelegramReceived += new EventHandler<UnknownDataReceivedEventArgs>(UnknownTelegramReceived);

      // This will send a UDP broadcast to port 1460.
      settings.Find();

      // The Find() method returns immediately, so we wait here to avoid closing the program.
      lock (lck)
      {
        Console.WriteLine();
        Console.WriteLine("Press any key to exit.");
        Console.WriteLine();
      }

      Console.ReadKey();
    }

    /// <summary>
    /// This event handler will be called when a reply message from a transiever arrives.
    /// The event handler code must be thread safe because several events can fire at the same time.
    /// </summary>
    /// <param name="sender">The object that sent the event.</param>
    /// <param name="e">The event data.</param>
    private static void TransieverInfoReceived(object sender, TransieverInfoReceivedEventArgs e)
    {
      // The Settings object.
      Settings settings = (Settings)sender;

      // The server address we want.
      IPAddress server = IPAddress.Parse("192.168.188.4");

      // Check if the server address is already correct. If it is not, change it and update the transiever.
      if (!e.TransieverInfo.PeerIPAddress.Equals(server))
      {
        lock (lck)
        {
          Console.WriteLine();
          Console.WriteLine("The transiever with MAC address " + e.TransieverInfo.PhysicalAddress + " did not have the correct server address.");
          Console.WriteLine("Updating.");
        }
                
        e.TransieverInfo.PeerIPAddress = server;
        settings.Update(e.TransieverInfo);
      }
      else
      {
        // When updating, the transiever confirms the update by sending a TransieverInfo message again.
        lock (lck)
        {
          Console.WriteLine();
          Console.WriteLine("The transiever with MAC address " + e.TransieverInfo.PhysicalAddress + " already has the correct server address.");
          Console.WriteLine("No update needed.");
        }
      }
    }

    /// <summary>
    /// This event handler will be called when if unrecognizable information is received.
    /// The event handler code must be thread safe because several events can fire at the same time.
    /// </summary>
    /// <param name="sender">The object that sent the event.</param>
    /// <param name="e">The event data.</param>
    private static void UnknownTelegramReceived(object sender, UnknownDataReceivedEventArgs e)
    {
      lock (lck)
      {
        Console.WriteLine("Unknown telegram: " + Encoding.ASCII.GetString(e.Data));
        Console.WriteLine(e.Exception);
      }
    }
  }
}
